package org.light.generator;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;

import org.light.core.GinController;
import org.light.core.Writeable;
import org.light.domain.Domain;
import org.light.domain.Method;
import org.light.domain.Statement;
import org.light.exception.ValidateException;
import org.light.utils.DomainUtil;
import org.light.utils.StringUtil;
import org.light.utils.WriteableUtil;

public class InitDBGenerator{
	protected String fileName = "initdb.go";
	protected Domain sampleDomain;
	protected boolean isDummy = false;
	
	public InitDBGenerator(){
		this.fileName = "initdb.go";
	}
	
	public String generateString() throws ValidateException{
		if ("DataDummy".equalsIgnoreCase(sampleDomain.getSchema())|| this.isDummy == true) {
			return generateDummyString();
		} else {
			List<Writeable> sList = new ArrayList<Writeable>();
			sList.add(new Statement(1000L,0,"package database"));
			sList.add(new Statement(2000L,0,""));
			sList.add(new Statement(3000L,0,"import ("));
			sList.add(new Statement(4000L,1,"\"database/sql\""));
			sList.add(new Statement(5000L,1,"\"log\""));
			sList.add(new Statement(6000L,1,""));
			
			if (StringUtil.isBlank(this.sampleDomain.getDbType())||"MariaDB".equalsIgnoreCase(this.sampleDomain.getDbType())||"MariaDB".equalsIgnoreCase(this.sampleDomain.getDbType())||"MySQL".equalsIgnoreCase(this.sampleDomain.getDbType())) {
				sList.add(new Statement(7000L,1,"_ \"github.com/go-sql-driver/mysql\""));
			}else if ("PostgreSQL".equalsIgnoreCase(this.sampleDomain.getDbType())||"pgsql".equalsIgnoreCase(this.sampleDomain.getDbType())) {
				sList.add(new Statement(7000L,1,"_ \"github.com/lib/pq\""));
			}else if ("Oracle".equalsIgnoreCase(this.sampleDomain.getDbType())) {
				sList.add(new Statement(7000L,1,"_ \"github.com/godror/godror\""));
			}else {
				throw new ValidateException(this.sampleDomain.getDbType()+"数据库不被支持！");
			}
	
			sList.add(new Statement(8000L,1,"\"github.com/spf13/viper\""));
			sList.add(new Statement(9000L,0,")"));
			sList.add(new Statement(10000L,0,""));
			sList.add(new Statement(11000L,0,"var DB *sql.DB"));
			sList.add(new Statement(12000L,0,""));
			sList.add(new Statement(13000L,0,"func Init() error {"));
			sList.add(new Statement(14000L,1,"var err error"));
			sList.add(new Statement(15000L,0,""));
			
			if (StringUtil.isBlank(this.sampleDomain.getDbType())||"MariaDB".equalsIgnoreCase(this.sampleDomain.getDbType())||"MariaDB".equalsIgnoreCase(this.sampleDomain.getDbType())||"MySQL".equalsIgnoreCase(this.sampleDomain.getDbType())) {
				sList.add(new Statement(16000L,1,"DB, err = sql.Open(\"mysql\", viper.GetString(\"mysql.source_name\"))"));
			}else if ("PostgreSQL".equalsIgnoreCase(this.sampleDomain.getDbType())||"pgsql".equalsIgnoreCase(this.sampleDomain.getDbType())) {
				sList.add(new Statement(16000L,1,"DB, err = sql.Open(\"postgres\", viper.GetString(\"postgresql.source_name\"))"));
			}else if ("Oracle".equalsIgnoreCase(this.sampleDomain.getDbType())) {
				sList.add(new Statement(16000L,1,"DB, err = sql.Open(\"godror\", viper.GetString(\"oracle.source_name\"))"));
			}else {
				throw new ValidateException(this.sampleDomain.getDbType()+"数据库不被支持！");
			}
			
			sList.add(new Statement(17000L,1,"if nil != err {"));
			sList.add(new Statement(18000L,2,"return err"));
			sList.add(new Statement(19000L,1,"}"));
			sList.add(new Statement(20000L,0,""));
			
			if (StringUtil.isBlank(this.sampleDomain.getDbType())||"MariaDB".equalsIgnoreCase(this.sampleDomain.getDbType())||"MariaDB".equalsIgnoreCase(this.sampleDomain.getDbType())||"MySQL".equalsIgnoreCase(this.sampleDomain.getDbType())) {
				sList.add(new Statement(21000L,1,"DB.SetMaxIdleConns(viper.GetInt(\"mysql.max_idle_conns\"))"));
			}else if ("PostgreSQL".equalsIgnoreCase(this.sampleDomain.getDbType())||"pgsql".equalsIgnoreCase(this.sampleDomain.getDbType())) {
				sList.add(new Statement(21000L,1,"DB.SetMaxIdleConns(viper.GetInt(\"postgresql.max_idle_conns\"))"));
			}else if ("Oracle".equalsIgnoreCase(this.sampleDomain.getDbType())) {
				sList.add(new Statement(21000L,1,"DB.SetMaxIdleConns(viper.GetInt(\"oracle.max_idle_conns\"))"));
			}else {
				throw new ValidateException(this.sampleDomain.getDbType()+"数据库不被支持！");
			}
	
			sList.add(new Statement(22000L,0,""));
			sList.add(new Statement(23000L,1,"err = DB.Ping()"));
			sList.add(new Statement(24000L,1,"if nil != err {"));
			sList.add(new Statement(25000L,2,"return err"));
			sList.add(new Statement(26000L,1,"} else {"));
			sList.add(new Statement(27000L,2,"log.Println(\"Database Startup Normal!\")"));
			sList.add(new Statement(28000L,1,"}"));
			sList.add(new Statement(29000L,1,"return nil"));
			sList.add(new Statement(30000L,0,"}"));
			return WriteableUtil.merge(sList).getContent();
		}
	}
	
	public String generateDummyString() throws ValidateException{
		List<Writeable> sList = new ArrayList<Writeable>();
		sList.add(new Statement(1000L,0,"package database"));
		sList.add(new Statement(2000L,0,""));
		sList.add(new Statement(3000L,0,"import ("));
		sList.add(new Statement(4000L,1,"\"database/sql\""));
		sList.add(new Statement(9000L,0,")"));
		sList.add(new Statement(10000L,0,""));
		sList.add(new Statement(11000L,0,"var DB *sql.DB"));
		sList.add(new Statement(12000L,0,""));
		sList.add(new Statement(13000L,0,"func Init() error {"));
		sList.add(new Statement(29000L,1,"return nil"));
		sList.add(new Statement(30000L,0,"}"));
		return WriteableUtil.merge(sList).getContent();
	}

	public Domain getSampleDomain() {
		return sampleDomain;
	}

	public void setSampleDomain(Domain sampleDomain) {
		this.sampleDomain = sampleDomain;
	}

	public String getFileName() {
		return fileName;
	}

	public void setFileName(String fileName) {
		this.fileName = fileName;
	}

	public boolean isDummy() {
		return isDummy;
	}

	public void setDummy(boolean isDummy) {
		this.isDummy = isDummy;
	}
}
